package com.evan.review.thread;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.evan.review.R;

import java.lang.ref.WeakReference;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Activity demonstrating different thread creation and usage methods in Android
 */
public class ThreadExampleActivity extends AppCompatActivity {
    private static final String TAG = "ThreadExampleActivity";
    
    private TextView tvStatus;
    private ProgressBar progressBar;
    private Button btnThread;
    private Button btnRunnable;
    private Button btnCallable;
    private Button btnHandler;
    private Button btnStopAll;
    
    // Example of thread creation using Handler
    private MyHandler mHandler;
    
    // Thread flag for cancellation
    private volatile boolean isRunning = true;
    
    // Thread objects to manage
    private Thread threadExample;
    private Thread runnableThread;
    private Thread callableThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_thread_example);
        
        initViews();
        setupListeners();
        
        // Initialize handler with current activity
        mHandler = new MyHandler(this);
    }
    
    private void initViews() {
        tvStatus = findViewById(R.id.tv_status);
        progressBar = findViewById(R.id.progress_bar);
        btnThread = findViewById(R.id.btn_thread);
        btnRunnable = findViewById(R.id.btn_runnable);
        btnCallable = findViewById(R.id.btn_callable);
        btnHandler = findViewById(R.id.btn_handler);
        btnStopAll = findViewById(R.id.btn_stop_all);
    }
    
    private void setupListeners() {
        // 1. Thread creation by extending Thread class
        btnThread.setOnClickListener(v -> {
            isRunning = true;
            threadExample = new CounterThread();
            threadExample.start();
        });
        
        // 2. Thread creation by implementing Runnable interface
        btnRunnable.setOnClickListener(v -> {
            isRunning = true;
            CounterRunnable runnable = new CounterRunnable();
            runnableThread = new Thread(runnable);
            runnableThread.start();
        });
        
        // 3. Thread creation using Callable and FutureTask
        btnCallable.setOnClickListener(v -> {
            isRunning = true;
            CounterCallable callable = new CounterCallable();
            FutureTask<Integer> futureTask = new FutureTask<>(callable);
            callableThread = new Thread(futureTask);
            callableThread.start();
            
            // Getting result from FutureTask requires another thread to avoid blocking UI
            new Thread(() -> {
                try {
                    final Integer result = futureTask.get(); // This blocks until callable completes
                    runOnUiThread(() -> {
                        tvStatus.setText("Callable结果: " + result);
                    });
                } catch (ExecutionException | InterruptedException e) {
                    Log.e(TAG, "Error getting result from callable", e);
                }
            }).start();
        });
        
        // 4. Thread communication using Handler
        btnHandler.setOnClickListener(v -> {
            isRunning = true;
            new Thread(() -> {
                try {
                    for (int i = 0; i <= 10 && isRunning; i++) {
                        // Send message to handler
                        Message msg = Message.obtain();
                        msg.what = 0;
                        msg.arg1 = i;
                        mHandler.sendMessage(msg);
                        Thread.sleep(500);
                    }
                } catch (InterruptedException e) {
                    Log.e(TAG, "Thread interrupted", e);
                }
            }).start();
        });
        
        // Stop all running threads
        btnStopAll.setOnClickListener(v -> {
            isRunning = false;
            tvStatus.setText("所有线程已停止");
            progressBar.setProgress(0);
            
            // Interrupt threads if needed
            safelyInterruptThread(threadExample);
            safelyInterruptThread(runnableThread);
            safelyInterruptThread(callableThread);
            
            Toast.makeText(this, "All threads stopped", Toast.LENGTH_SHORT).show();
        });
    }
    
    // Method to safely interrupt a thread
    private void safelyInterruptThread(Thread thread) {
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
        }
    }
    
    // 1. Thread Example - Extending Thread class
    private class CounterThread extends Thread {
        @Override
        public void run() {
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            try {
                for (int i = 0; i <= 100 && isRunning; i += 10) {
                    final int progress = i;
                    Log.d(TAG, "CounterThread: " + progress);
                    
                    // Update UI on main thread
                    runOnUiThread(() -> {
                        tvStatus.setText("线程进度: " + progress + "%");
                        progressBar.setProgress(progress);
                    });
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                Log.e(TAG, "CounterThread interrupted", e);
            }
        }
    }
    
    // 2. Runnable Example - Implementing Runnable interface
    private class CounterRunnable implements Runnable {
        @Override
        public void run() {
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            try {
                for (int i = 0; i <= 100 && isRunning; i += 20) {
                    final int progress = i;
                    Log.d(TAG, "CounterRunnable: " + progress);
                    
                    // Alternative way to update UI
                    Handler mainHandler = new Handler(Looper.getMainLooper());
                    mainHandler.post(() -> {
                        tvStatus.setText("Runnable进度: " + progress + "%");
                        progressBar.setProgress(progress);
                    });
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                Log.e(TAG, "CounterRunnable interrupted", e);
            }
        }
    }
    
    // 3. Callable Example - Implementing Callable interface with return value
    private class CounterCallable implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            int totalProgress = 0;
            
            try {
                for (int i = 0; i <= 100 && isRunning; i += 25) {
                    final int progress = i;
                    totalProgress = progress;
                    Log.d(TAG, "CounterCallable: " + progress);
                    
                    // Update UI using View.post()
                    progressBar.post(() -> {
                        tvStatus.setText("Callable进度: " + progress + "%");
                        progressBar.setProgress(progress);
                    });
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                Log.e(TAG, "CounterCallable interrupted", e);
            }
            
            return totalProgress; // Return the final progress value
        }
    }
    
    // 4. Handler Example - Using static inner class to avoid memory leaks
    private static class MyHandler extends Handler {
        // WeakReference to avoid memory leaks
        private final WeakReference<ThreadExampleActivity> activityReference;
        
        public MyHandler(ThreadExampleActivity activity) {
            super(Looper.getMainLooper());
            activityReference = new WeakReference<>(activity);
        }
        
        @Override
        public void handleMessage(@NonNull Message msg) {
            ThreadExampleActivity activity = activityReference.get();
            if (activity == null || !activity.isRunning) {
                return;
            }
            
            switch (msg.what) {
                case 0:
                    int progress = msg.arg1 * 10;
                    activity.tvStatus.setText("Handler进度: " + progress + "%");
                    activity.progressBar.setProgress(progress);
                    break;
            }
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Clean up to avoid memory leaks
        isRunning = false;
        
        // Remove all callbacks and messages
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
        }
        
        // Interrupt all threads
        safelyInterruptThread(threadExample);
        safelyInterruptThread(runnableThread);
        safelyInterruptThread(callableThread);
    }
} 